#ifndef BSONDOC_INCLUDED
#define BSONDOC_INCLUDED

#include "mongoc.h"
#include <stdarg.h>
#include <string>
#include <map>

using std::string;
using std::map;

#define BSONDOC_APPEND(_bson, ...) \
    BCON_APPEND(_bson,__VA_ARGS__)

class BsonDoc
{
public:
    BsonDoc()
    {
        m_doc = bson_new();
    }
    
    ~BsonDoc()
    {
        if ( m_doc != NULL )
            bson_destroy( m_doc );
    }

    bson_t* doc()
    {
        return m_doc;
    }

    // 构造，使用 BCON_APPEND 或 BSONDOC_APPEND
    // see driver example
    //
    // BCON_APPEND (&bcon, "foo", BCON_OID (&oid));
    //
    // BCON_APPEND (&bcon, "foo", BCON_NULL);
    //
    // BCON_APPEND (&bcon, "foo", BCON_DOUBLE (1.1));
    //
    // bson_decimal128_t dec;
    // bson_decimal128_from_string ("120E20", &dec);
    // BCON_APPEND (&bcon, "foo", BCON_DECIMAL128 (&dec));
    //
    // BCON_APPEND (&bcon,
    //             "foo",
    //             BCON_BIN (BSON_SUBTYPE_BINARY, (const uint8_t *) "deadbeef", 8),
    //             NULL);
    //
    // BCON_APPEND (&bcon, "foo", BCON_REGEX ("^foo|bar$", "msi"));
    // BCON_APPEND (&bcon, "foo", BCON_CODE ("var a = {};"));
    // BCON_APPEND (&bcon, "foo", BCON_SYMBOL ("deadbeef"));
    // BCON_APPEND (&bcon, "foo", BCON_CODEWSCOPE ("var a = b;", &scope));
    // BCON_APPEND (&bcon, "foo", BCON_INT32 (100));
    // BCON_APPEND (&bcon, "foo", BCON_TIMESTAMP (100, 1000));
    // BCON_APPEND (&bcon, "foo", BCON_INT64 (100));
    // BCON_APPEND (&bcon, "foo", BCON_MAXKEY);
    // BCON_APPEND (&bcon, "foo", BCON_MINKEY);
    // BCON_APPEND (&bcon, "foo", BCON_DOCUMENT (&child));
    // BCON_APPEND (&bcon, "foo", BCON_ARRAY (&child));
    // BCON_APPEND (&bcon, "foo", "[", "baz", "]");
    // BCON_APPEND (&bcon, "foo", "{", "bar", "baz", "}");
    // BCON_APPEND (&bcon, "$set", "{", "bar", "baz", "}");
    /*
    BCON_APPEND (&bcon,
            "foo",
            "{",
                "bar",
                    "[",
                        BCON_INT32 (1),
                        BCON_INT32 (2),
                        "{","hello","world","}",
                    "]",
            "}"
            );
    // { "_id" : ObjectId("5c3d96f75e088449dd704822"), "foo" : { "bar" : [ 1, 2, { "hello" : "world" } ] } }
    */
    // BCON_APPEND (&bcon, "foo", "[", "bar", BCON (&child2), "]");


    void initid();
    void setid(const string& id);
    static string getid(bson_t* pdoc);

    // tojson时, 会保留 mongoc api 返回字符串中的 $,
    string toJson();
    static string toJson(bson_t* pdoc);
    static string toJson(mongoc_cursor_t *pcursor);
        // 返回一个json数组 字符串

    static string& trim(string& str, const string& trimstr = "$");
        // 去掉所有 trimstr
private:
    bson_t      *m_doc;
};

#endif

